﻿using System.Collections.Generic;
using System.Text;
using System.IO;
using System;

namespace ServerFramework.Net.Msg
{
    public class MsgUsn:IDisposable
    {
        BinaryReader reader;
        MemoryStream stream;

        public MsgUsn(byte [] data)
        {
            stream = new MemoryStream(data);
            reader = new BinaryReader(stream, Encoding.UTF8);
        }
        public MsgUsn Read(ref int val)
        {
            val = reader.ReadInt32();
            return this;
        }
        public MsgUsn Read(ref uint val)
        {
            val = (uint)reader.ReadInt32();
            return this;
        }
        public MsgUsn Read(ref short val)
        {
            val = reader.ReadInt16();
            return this;
        }
        public MsgUsn Read(ref ushort val)
        {
            val = (ushort)reader.ReadInt16();
            return this;
        }
        public MsgUsn Read(ref byte val)
        {
            val = reader.ReadByte();
            return this;
        }
        public MsgUsn Read(ref long val)
        {
            val = reader.ReadInt64();
            return this;
        }
        public MsgUsn Read(ref float val)
        {
            val = reader.ReadSingle();
            return this;
        }
        public MsgUsn Read(ref bool val)
        {
            val = reader.ReadBoolean();
            return this;
        }
        public MsgUsn Read(out string val)
        {
            int len = reader.ReadInt32();
            byte[] buffer = reader.ReadBytes(len);
            val = Encoding.UTF8.GetString(buffer);
            return this;
        }

        public MsgUsn Read(out DateTime val)
        {
            long time_t = 0;
            Read(ref time_t);
            double seconds = time_t + 28800;
            double secs = Convert.ToDouble(seconds);
            DateTime dt = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Unspecified).AddSeconds(secs);
            val = dt;
            return this;
        }

        public MsgUsn Read(out byte[] val)
        {
            int len = reader.ReadInt32();
            val = reader.ReadBytes(len);
            return this;
        }
        public MsgUsn Read<T>(List<T> val) where T : ISn, new()
        {
            int len = reader.ReadInt32();
            for (int i = 0; i < len; ++i)
            {
                T tmp = new T();
                this.Read(ref tmp);
                val.Add(tmp);
            }
            return this;
        }
        public MsgUsn Read(List<int> val)
        {
            int len = reader.ReadInt32();
            for (int i = 0; i < len; ++i)
            {
                int tmp = 0;
                this.Read(ref tmp);
                val.Add(tmp);
            }
            return this;
        }
        public MsgUsn Read(List<uint> val)
        {
            int len = reader.ReadInt32();
            for (int i = 0; i < len; ++i)
            {
                uint tmp = 0;
                this.Read(ref tmp);
                val.Add(tmp);
            }
            return this;
        }
        public MsgUsn Read(List<short> val)
        {
            int len = reader.ReadInt32();
            for (int i = 0; i < len; ++i)
            {
                short tmp = 0;
                this.Read(ref tmp);
                val.Add(tmp);
            }
            return this;
        }
        public MsgUsn Read(List<ushort> val)
        {
            int len = reader.ReadInt32();
            for (int i = 0; i < len; ++i)
            {
                ushort tmp = 0;
                this.Read(ref tmp);
                val.Add(tmp);
            }
            return this;
        }
        public MsgUsn Read(List<byte> val)
        {
            int len = reader.ReadInt32();
            for (int i = 0; i < len; ++i)
            {
                byte tmp = 0;
                this.Read(ref tmp);
                val.Add(tmp);
            }
            return this;
        }
        public MsgUsn Read(List<long> val)
        {
            int len = reader.ReadInt32();
            for (int i = 0; i < len; ++i)
            {
                long tmp = 0;
                this.Read(ref tmp);
                val.Add(tmp);
            }
            return this;
        }
        public MsgUsn Read(List<string> val)
        {
            int len = reader.ReadInt32();
            for (int i = 0; i < len; ++i)
            {
                string tmp;
                this.Read(out tmp);
                val.Add(tmp);
            }
            return this;
        }
        public MsgUsn Read(Dictionary<string, byte[]> val)
        {
            int len = reader.ReadInt32();
            for (int i = 0; i < len; ++i)
            {
                string key = "";
                this.Read(out key);
                byte[] valu = null;
                this.Read(out valu);
                val.Add(key, valu);
            }
            return this;
        }
        public MsgUsn Read<K, V>(Dictionary<K, V> val)
            where K : ISn, new()
            where V : ISn, new()
        {
            int len = reader.ReadInt32();
            for (int i = 0; i < len; ++i)
            {
                K ktmp = new K();
                this.Read(ref ktmp);
                V vtmp = new V();
                this.Read(ref vtmp);
                val.Add(ktmp, vtmp);
            }
            return this;
        }
        public MsgUsn Read<V>(Dictionary<int, V> val) where V : ISn, new()
        {
            int len = reader.ReadInt32();
            for (int i = 0; i < len; ++i)
            {
                int ktmp = 0;
                this.Read(ref ktmp);
                V vtmp = new V();
                this.Read(ref vtmp);
                val.Add(ktmp, vtmp);
            }
            return this;
        }
        public MsgUsn Read<V>(Dictionary<long, V> val) where V : ISn, new()
        {
            int len = reader.ReadInt32();
            for (int i = 0; i < len; ++i)
            {
                int ktmp = 0;
                this.Read(ref ktmp);
                V vtmp = new V();
                this.Read(ref vtmp);
                val.Add(ktmp, vtmp);
            }
            return this;
        }
        public MsgUsn Read(Dictionary<int, long> val)
        {
            int len = reader.ReadInt32();
            for (int i = 0; i < len; ++i)
            {
                int ktmp = 0;
                this.Read(ref ktmp);
                long vtmp = 0;
                this.Read(ref vtmp);
                val.Add(ktmp, vtmp);
            }
            return this;
        }
        public MsgUsn Read(Dictionary<int, int> val)
        {
            int len = reader.ReadInt32();
            for (int i = 0; i < len; ++i)
            {
                int ktmp = 0;
                this.Read(ref ktmp);
                int vtmp = 0;
                this.Read(ref vtmp);
                val.Add(ktmp, vtmp);
            }
            return this;
        }
        public MsgUsn Read(Dictionary<int, uint> val)
        {
            int len = reader.ReadInt32();
            for (int i = 0; i < len; ++i)
            {
                int ktmp = 0;
                this.Read(ref ktmp);
                uint vtmp = 0;
                this.Read(ref vtmp);
                val.Add(ktmp, vtmp);
            }
            return this;
        }
        public MsgUsn Read(Dictionary<int, ushort> val)
        {
            int len = reader.ReadInt32();
            for (int i = 0; i < len; ++i)
            {
                int ktmp = 0;
                this.Read(ref ktmp);
                ushort vtmp = 0;
                this.Read(ref vtmp);
                val.Add(ktmp, vtmp);
            }
            return this;
        }
        public MsgUsn Read(Dictionary<int, float> val)
        {
            int len = reader.ReadInt32();
            for (int i = 0; i < len; ++i)
            {
                int ktmp = 0;
                this.Read(ref ktmp);
                float vtmp = 0;
                this.Read(ref vtmp);
                val.Add(ktmp, vtmp);
            }
            return this;
        }
        public MsgUsn Read(Dictionary<int, string> val)
        {
            int len = reader.ReadInt32();
            for (int i = 0; i < len; ++i)
            {
                int ktmp = 0;
                this.Read(ref ktmp);
                string vtmp;
                this.Read(out vtmp);
                val.Add(ktmp, vtmp);
            }
            return this;
        }
        public MsgUsn Read(Dictionary<ushort, int> val)
        {
            int len = reader.ReadInt32();
            for (int i = 0; i < len; ++i)
            {
                ushort ktmp = 0;
                this.Read(ref ktmp);
                int vtmp = 0;
                this.Read(ref vtmp);
                val.Add(ktmp, vtmp);
            }
            return this;
        }
        public MsgUsn Read(Dictionary<ushort, ushort> val)
        {
            int len = reader.ReadInt32();
            for (int i = 0; i < len; ++i)
            {
                ushort ktmp = 0;
                this.Read(ref ktmp);
                ushort vtmp = 0;
                this.Read(ref vtmp);
                val.Add(ktmp, vtmp);
            }
            return this;
        }
        public MsgUsn Read(Dictionary<ushort, string> val)
        {
            int len = reader.ReadInt32();
            for (int i = 0; i < len; ++i)
            {
                ushort ktmp = 0;
                this.Read(ref ktmp);
                string vtmp;
                this.Read(out vtmp);
                val.Add(ktmp, vtmp);
            }
            return this;
        }
        public MsgUsn Read(Dictionary<string, int> val)
        {
            int len = reader.ReadInt32();
            for (int i = 0; i < len; ++i)
            {
                string ktmp;
                this.Read(out ktmp);
                int vtmp = 0;
                this.Read(ref vtmp);
                val.Add(ktmp, vtmp);
            }
            return this;
        }
        public MsgUsn Read(Dictionary<string, ushort> val)
        {
            int len = reader.ReadInt32();
            for (int i = 0; i < len; ++i)
            {
                string ktmp;
                this.Read(out ktmp);
                ushort vtmp = 0;
                this.Read(ref vtmp);
                val.Add(ktmp, vtmp);
            }
            return this;
        }

        public MsgUsn Read(Dictionary<string, string> val)
        {
            int len = reader.ReadInt32();
            for (int i = 0; i < len; ++i)
            {
                string ktmp;
                this.Read(out ktmp);
                string vtmp;
                this.Read(out vtmp);
                val.Add(ktmp, vtmp);
            }
            return this;
        }
        public MsgUsn Read<T>(ref T val) where T : ISn
        {
            val.Usn(this);
            return this;
        }

        public void Dispose()
        {
            if(stream != null)
            {
                stream.Close();
            }
            if (reader != null)
            {
                reader.BaseStream.Close();
                reader.Close();
            }
        }
    }
}
